home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 25
/
Aminet 25 (1998)(GTI - Schatztruhe)[!][Jun 1998].iso
/
Aminet
/
util
/
pack
/
xpk_Source.lha
/
xpk_Source
/
Oberon
/
rlen
/
xpkRLen.mod
next >
Wrap
Text File
|
1998-02-08
|
5KB
|
189 lines
(*************************************************************************
:Program. xpkRLen.mod
:Contents. demo XpkSub library
:Author. Hartmut Goebel [hG]
:Language. Oberon
:Translator. Amiga Oberon V2.13
:History. V0.9, 11 Jan 1992 Hartmut Goebel [hG]
:History. V1.0, 27 Jul 1992 [hG] working but not really tested!
:Date. 27 Jul 1992 12:30:14
*************************************************************************)
(*
* IMPORTANT:
* The packing algorithm of this Lib has not been tested to be proof!
*
* It is only a demo to show how to make XPK-Libs with AmigaOberon
* Just compile this using SMALLCODE, SMALLDATA and link it by
* 'LibLink with xpkRLen.wth'. Done.
*)
MODULE xpkRLen;
IMPORT
s := SYSTEM,
xpk:= XpkMaster,
xs := XpkSubDefs;
CONST
RLEN = s.VAL(LONGINT,"RLEN");
RlenMode = xpk.XpkMode(
NIL, (* next *)
100, (* upto *)
LONGSET{xpk.mfA3000Speed},(* flags *)
0, (* packmem *)
0, (* unpackmem *)
140, (* packspeed, K/sec *)
1043, (* unpackspeed, K/sec *)
45, (* ratio, *0.1% *)
0, (* reserved *)
"normal"); (* description *)
RlenInfo = xs.XpkInfo(
1, (* info version *)
0, (* lib version *)
0, (* master vers *)
0, (* pad *)
s.ADR("RLEN"), (* short name *)
s.ADR("Run Length 1.0"), (* long name *)
s.ADR("Fast and simple compression usable for simple data"), (* description*)
RLEN, (* 4 letter ID *)
LONGSET{xs.pkChunk,xs.upChunk}, (* flags *)
32000, (* max in chunk *)
0, (* min in chunk *)
32000, (* def in chunk *)
NIL, (* pk message *)
NIL, (* up message *)
NIL, (* pk past msg *)
NIL, (* up past msg *)
50, (* def mode *)
0, (* pad *)
s.ADR(RlenMode), (* modes *)
0,0,0,0,0,0); (* reserved *)
TYPE
BufferPtr = POINTER TO ARRAY MAX(LONGINT)-1 OF BYTE;
(*
* Returns an info structure about our packer
*)
PROCEDURE XpksPackerInfo * (): xs.XpkInfoPtr;
(* No need for SaveRegs here, cause only d0 will be used! *)
BEGIN
RETURN s.ADR(RlenInfo);
END XpksPackerInfo;
PROCEDURE XpksPackFree * (params{8}: xs.XpkSubParamsPtr);
BEGIN
END XpksPackFree;
(*
* This forces the next chunk to be uncompressable independent from the
* previous one. This is always the case in RLEN.
*)
PROCEDURE XpksPackReset * (params{8}: xs.XpkSubParamsPtr): LONGINT;
(* No need for SaveRegs here, cause only d0 will be used! *)
BEGIN
RETURN 0;
END XpksPackReset;
PROCEDURE XpksUnpackFree * (params{8}: xs.XpkSubParamsPtr);
BEGIN
END XpksUnpackFree;
(*
* Pack a chunk
*)
PROCEDURE XpksPackChunk * (xpar{8}: xs.XpkSubParamsPtr): LONGINT;
(* $SaveRegs+ *)
VAR
get, put: BufferPtr;
i: INTEGER;
in, out, start, end: LONGINT;
run: BOOLEAN; v: CHAR;
BEGIN
get := xpar.inBuf;
put := xpar.outBuf;
end := xpar.inLen;
in := 0; out := 0; start := 0;
LOOP
run := (get[0]=get[1]) & (get[0]=get[2]);
IF in+out+4 > xpar.outBufLen THEN
RETURN xpk.errExpansion; END;
IF run OR (in-start=127) OR (in=end) THEN (* write uncompressed *)
IF in-start # 0 THEN
put[out] := CHR(in-start); INC(out);
i := SHORT(in-start);
REPEAT
put[out] := get[start]; INC(out); INC(start);
DEC(i);
UNTIL i = 0;
END;
IF in = end THEN
put[out] := CHR(0); INC(out);
EXIT;
END;
start := in;
END;
IF run THEN (* write compressed *)
v := get[i];
i := 3;
WHILE (in+i<end) & (get[in+i]=v) & (i<127) DO
INC(i); END;
put[out] := CHR(-i); INC(out);
put[out] := v; INC(out);
INC(in,i);
start := in;
ELSE
INC(in);
END;
END;
xpar.outLen := out;
RETURN 0;
END XpksPackChunk;
PROCEDURE XpksUnpackChunk * (xpar{8}: xs.XpkSubParamsPtr): LONGINT;
(* $SaveRegs+ *)
VAR
i: INTEGER;
get, put: BufferPtr;
in, out: LONGINT;
v: CHAR;
BEGIN
get := xpar.inBuf;
put := xpar.outBuf;
in := 0; out := 0;
LOOP
i := ORD(get[in]);
IF i = 0 THEN EXIT; END;
INC(in);
IF i > 0 THEN
REPEAT
put[out]:=get[in]; INC(out); INC(in);
DEC(i);
UNTIL i = 0;
ELSE
v := get[in]; INC(in);
REPEAT
put[out]:=v; INC(out);
INC(i);
UNTIL i = 0;
END;
END;
RETURN 0;
END XpksUnpackChunk;
END xpkRLen.